home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Trading on the Edge
/
Trading On The Edge - CD-ROM Toolkit (Wayzata Technology)(2031)(1994).bin
/
pc
/
mac_file
/
software
/
nn_prepr
/
findic.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-25
|
13KB
|
420 lines
/* 11:58 15-Aug-92 (findic.c) Dictionary Management for Financial Rtnes */
#include "fin.h"
/************************************************************************
* Copyright(C) 1992 High-Tech Communications. *
* 103 Buckskin Court, Sewickley, PA 15143 *
* *
* Written by Casimir C. Klimasauskas *
* *
* All rights reserved. No part of this program may be reproduced, *
* stored in a retrieval system, or tramsmitted, in any form or by any *
* means, electronic, mechanical, photocopying, recording or otherwise *
* without the prior written permission of the copyright owner, *
* High-Tech Communications. *
* *
* These programs are supplied on an "as-is" basis with no warranties *
* of fitness or operability, either express or implied. *
* *
************************************************************************
*/
/************************************************************************
* *
* Dictionary Routines for Storing "strings" *
* *
************************************************************************
Date2BinL( cp ) - convert a date to long
Date2StrCP( l ) - convert a long to a date
DCFreeV( ) - free the dictionary
DCInitV( size ) - initialize the dictionary
DCLwrPkCP( cp ) - convert to lower case & pack characters
DCDupCP( cp ) - find or allocate a string
*/
typedef struct _dict { /* dictionary entry */
struct _dict *DNextP; /* next item in chain */
char DStr[1]; /* string itself */
} DICT;
char *DictBlkCP = {0}; /* dictionary block */
long DictSizeL = {0}; /* size of dictionary */
long DictCurXL = {0}; /* current index into dictionary */
DICT *DictHash[128] = {0}; /* hash table for string */
/************************************************************************
* *
* Asc2NumD() - convert an ascii string to a number *
* *
************************************************************************
This routine is designed to handle a variety of number data types:
[+|-]nnn[,]nnn.nn - floating point number
[+|-]n[,]nnn nnn/nnn - quote
It tries to classify the number type by counting the number of "/"'s in
the string. It then performs the proper de-composition to handle the
number.
*/
double Asc2NumD( iCP, nc ) /* convert ascii string to a number */
char *iCP; /* string pointer */
int nc; /* # of characters (max) in string */
{
int wxI; /* work index */
int nslash; /* # of slashes */
char *sp, *dp; /* work string pointers */
char *lnbp; /* last non-blank character */
int exp; /* exponent */
double rv; /* return value */
double num; /* numerator */
double den; /* denominator */
int fracf; /* fraction flag */
int c; /* work char */
int sign=0; /* sign of the answer */
char sbf[40]; /* work buffer */
dp = (char *)0; /* null until first non-blank char */
nslash = 0; /* # of slashes */
lnbp = (char *)0;
for( sp=iCP,wxI=nc; (c = *sp)!=0 && wxI>0; sp++,wxI-- ) {
if ( c == '/' ) nslash++;
if ( c > ' ' && dp == (char *)0 ) dp = &sbf[0];
if ( 'A' <= c && c <= 'Z' ) c -= 'A'-'a';
if ( dp ) *dp++ = c;
if ( c > ' ' ) lnbp = dp;
}
if ( dp == (char *)0 ) goto BadNumber;
*dp = 0; /* null terminate */
if ( lnbp != (char *)0 ) *lnbp = 0; /* truncate trailing spaces */
/* --- Check for special numbers --- */
if ( strcmp( sbf, "na" ) == 0 ||
strcmp( sbf, "hol" ) == 0 ||
strcmp( sbf, "nd" ) == 0 ||
strcmp( sbf, "n/a" ) == 0 ) {
rv = 0.0;
goto GoodNumber;
}
/* translate the number */
exp = -1;
rv = 0.0;
num = 0.0;
den = 0.0;
fracf = 0;
sp = &sbf[0];
if ( (c = *sp) == '+' ) sign = 1, sp++;
else if ( c == '-' ) sign = -1, sp++;
for( c = *sp; ('0'<=c && c<='9') || c=='.' || c==','; c = *sp ) {
sp++;
if ( c == ',' ) continue; /* ignore commas */
if ( c == '.' ) {
if ( exp >= 0 ) {
fprintf( stderr, "illegal number <%s>: multiple decimals\n",
sbf );
goto BadNumber;
}
exp = 0;
continue;
}
rv = rv * 10. + (c - '0');
if ( exp >= 0 ) exp++;
}
/* account for fractional part of the number */
for(; exp >= 3; exp -= 3 ) rv *= .001;
for(; exp > 0; exp-- ) rv *= .1;
/* if there is a fraction, convert it too */
if ( nslash == 0 ) goto GoodNumber;
/* convert the fraction */
while( *sp == ' ' ) sp++;
for( c = *sp; '0' <= c && c <= '9'; c = *sp ) {
sp++;
num = (10. * num) + (c - '0');
}
if ( c != '/' ) {
fprintf( stderr, "illegal format number <%s>: missing /\n", sbf );
goto BadNumber;
}
for( c = *++sp; '0' <= c && c <= '9'; c = *sp ) {
sp++;
den = (10. * den) + (c - '0');
}
if ( den != 0.0 ) rv += num / den; /* merge fraction with whole part */
GoodNumber:
if ( *sp != 0 ) {
fprintf( stderr, "illegal number format: embedded spaces <%s>\n", sbf );
}
if ( sign < 0 && rv != 0.0 ) rv = 0 - rv;
return( rv );
BadNumber:
return( 0.0 );
}
/* --- Date2BinL() ---
* Convert a date to a binary number: packed decimal yyyymmdd
* formats accepted: mm/dd/yy, mm-dd-yy, dd-mmm-yy
*/
long Date2BinL( dCP ) /* convert a date to binary */
char *dCP; /* date string pointer */
{
int d,m,y; /* day, month, year */
long dL; /* resulting date */
register char *sp; /* work string pointer */
char *ap; /* alternate pointer */
int nasc; /* # of ascii characters */
int ndig; /* # of digits */
int noth; /* # of other characters */
int ndash; /* # of dashes */
int nslash; /* # of slashes */
char MosCA[] = {"janfebmaraprmayjunjulaugsepoctnovdec"};
if ( dCP == (char *)0 ) goto BadDate;
for( sp = dCP; *sp && *sp <= ' '; ) sp++;
if ( *sp == 0 ) goto BadDate;
nasc = ndig = noth = ndash = nslash = 0;
for( ap = sp; *ap > ' '; ap++ ) {
if ( *ap == '/' || *ap == '\\' ) nslash++;
else if ( *ap == '-' ) ndash++;
else if ( '0' <= *ap && *ap <= '9' ) ndig++;
else if ( 'a' <= *ap && *ap <= 'z' ) nasc++;
else if ( 'A' <= *ap && *ap <= 'Z' ) { nasc++;
*ap -= 'A' -'a';
} else noth++;
}
if ( noth != 0 ) goto BadDate; /* bad date */
if ( nasc == 3 && ndash == 2 && ndig > 2 ) {
/* must be dd-mmm-yy format */
for( d = 0; '0' <= *sp && *sp <= '9'; sp++ )
d = (d<<4) | (*sp & 0xf);
if ( *sp != '/' && *sp != '\\' && *sp != '-' )
goto BadDate;
sp++;
for( m = 0; m < 12; m++ )
if ( strncmp( &MosCA[3*m], sp, 3 ) == 0 ) break;
if ( m >= 12 ) goto BadDate;
m = (m%10) | ((m/10)<<4);
sp += 3;
if ( *sp != '/' && *sp != '\\' && *sp != '-' )
goto BadDate;
sp++;
for( y = 0; '0' <= *sp && *sp <= '9'; sp++ )
y = (y<<4) | (*sp & 0xf);
if ( y < 0x100 ) y += 0x1900;
} else if ( nasc == 0 && ndig > 2 ) {
/* must be mm/dd/yy or mm-dd-yy format */
for( m = 0; '0' <= *sp && *sp <= '9'; sp++ )
m = (m << 4) | (*sp & 0xf);
if ( *sp != '/' && *sp != '\\' && *sp != '-' )
goto BadDate;
sp++;
for( d = 0; '0' <= *sp && *sp <= '9'; sp++ )
d = (d << 4) | (*sp & 0xf);
if ( *sp != '/' && *sp != '\\' && *sp != '-' )
goto BadDate;
sp++;
for( y = 0; '0' <= *sp && *sp <= '9'; sp++ )
y = (y << 4) | (*sp & 0xf);
if ( y < 0x100 ) y += 0x1900;
} else goto BadDate; /* bad date format */
dL = (((long)y & 0x7fffL) << 16) | ((m & 0xff) << 8) | (d & 0xff);
Done:
#ifdef TEST1
printf( "Date2BinL: dCP=<%s> dL=%08lx\n", dCP, dL );
fflush( stdout );
#endif
return( dL );
BadDate:
dL = -1L;
goto Done;
}
/* --- Date2StrCP() ---
* Convert an internal format yyyymmdd date to a string: mm/dd/yy
*/
char *Date2StrCP( dateL )
long dateL; /* date as a long */
{
char *dp; /* destination pointer */
static char dCA[10] = {0};
dp = &dCA[0];
*dp++ = (int)(((dateL >> 12) & 0xf) | '0');
*dp++ = (int)(((dateL >> 8) & 0xf) | '0');
*dp++ = '/';
*dp++ = (int)(((dateL >> 4) & 0xf) | '0');
*dp++ = (int)(((dateL ) & 0xf) | '0');
*dp++ = '/';
*dp++ = (int)(((dateL >> 20) & 0xf) | '0');
*dp++ = (int)(((dateL >> 16) & 0xf) | '0');
*dp++ = 0;
#ifdef TEST1
printf( "Date2StrCP: dateL=%08lx str=<%s>\n", dateL, dCA );
fflush( stdout );
#endif
return( (char *)&dCA[0] );
}
/* --- DCClearV ---
* Clear the dictionary of everything. Do not release memory.
*/
void DCClearV()
{
int i; /* work index */
DictCurXL = 0;
for( i = 0; i < sizeof(DictHash)/sizeof(DictHash[0]); i++ )
DictHash[i] = (DICT *)0;
}
/* --- DCFreeV ---
* Free Memory in the dictionary
*/
void DCFreeV() /* free dicitonary */
{
int i; /* work index */
DCClearV(); /* clear out hash tables */
if ( DictBlkCP != (char *)0 ) free( (void *)DictBlkCP );
DictBlkCP = (char *)0;
DictSizeL = 0;
#ifdef TEST1
printf( "DCFreeV: done\n" );
fflush( stdout );
#endif
return;
}
/* --- DCInitV ---
* Allocate memory for dictionary. If memory already allocated,
* Free that memory. Reset all tables when done.
*/
void DCInitV( sizeL ) /* initialize the dictionary */
long sizeL; /* size to make (max 64K) */
{
char *wCP; /* work char pointer */
if ( sizeL <= 0 ) sizeL = 0x4000L; /* 16K */
if ( sizeL > 0xfff0L ) sizeL = 0xfff0L; /* max 64K */
if ( (wCP = malloc( (unsigned)sizeL )) == (char *)0 ) {
fprintf( stderr, "insufficient memory for dictionary (%ld)\n", sizeL );
exit( 2 );
}
DCFreeV();
DictBlkCP = (char *)wCP;
DictSizeL = sizeL;
#ifdef TEST1
printf( "DCInitV: sizeL=%08ld DictBlkCP=%08lx\n", sizeL, DictBlkCP );
fflush( stdout );
#endif
return;
}
/* --- DCLwrPkCP ---
* Convert to lower case & pack characters.
* Kill blanks & whitespace.
*/
char *DCLwrPkCP( sp ) /* convert to lower case & pack characters */
char *sp; /* string to pack in place */
{
char *sp0; /* return string */
char *dp; /* destination pointer */
int c; /* character */
#ifdef TEST1
printf( "DCLwrPkCP: sp=<%s>", sp );
fflush( stdout );
#endif
for( dp = sp0 = sp; (c = *sp & 0x7f) != 0; sp++ ) {
if ( 'A' <= c && c <= 'Z' ) c -= 'A' - 'a';
if ( c > ' ' ) *dp++ = c;
}
*dp = 0;
#ifdef TEST1
printf( " sp0=<%s>\n", sp0 );
fflush( stdout );
#endif
return( sp0 );
}
/* --- DCDupCP ---
* Find or duplicate a string. Use the first character as a
* "hash" value.
*/
char *DCDupCP( sp ) /* find / duplicate a string */
char *sp; /* string to find / duplicate */
{
DICT *wDP; /* work dictionary pointer */
DICT *pDP; /* previous dictionary pointer */
int wx; /* starting index */
if ( DictBlkCP == (char *)0 || DictSizeL == 0 )
DCInitV( 0L ); /* default initialization */
wx = *sp & 0x7f; /* hash index */
pDP = (DICT *)&DictHash[wx]; /* point to hash table */
while( (wDP = pDP->DNextP) != (DICT *)0 ) {
wx = strcmp( wDP->DStr, sp );
if ( wx == 0 )
return( &wDP->DStr[0] ); /* found the string */
if ( wx > 0 ) break; /* past the string */
pDP = wDP; /* link forward */
}
/* --- string was not found: add it --- */
wx = ((strlen(sp) + 4) & (-4)) + sizeof(DICT *);
if ( (wx + DictCurXL) > DictSizeL ) {
fprintf( stderr, "Dictionary full for <%s>!\n", sp );
exit( 3 );
}
wDP = (DICT *)(DictBlkCP + DictCurXL);
wDP->DNextP = pDP->DNextP; /* insert the new item in chain */
pDP->DNextP = wDP;
strcpy( &wDP->DStr[0], sp ); /* copy the string to dictionary */
DictCurXL += wx; /* update next free space */
#ifdef TEST1
printf( "DCDupCP: s=<%s> hx=%d p=%08lx wx=%d\n",
sp, *sp&0x7f, DictHash[*sp&0x7f], wx );
printf( " wDP=%08lx->%08lx pDP=%08lx->%08lx DictCurXL=%ld\n",
wDP, wDP->DNextP, pDP, pDP->DNextP, DictCurXL );
fflush( stdout );
#endif
return( &wDP->DStr[0] );
}